#include <raw_api.h>
#include <stdio.h>
#include <port_idle_config.h>
#include <bomb.h>

void Bomb4_ctor(Bomb4 *me, RAW_U8 defuse);

static RAW_U16 Bomb4_initial(Bomb4 *me, 	 	STATE_EVENT  *e);
static RAW_U16 Bomb4_setting(Bomb4 *me, 	STATE_EVENT  *e);
static RAW_U16 Bomb4_timing (Bomb4 *me, 	STATE_EVENT  *e);

Bomb4 l_bomb22;                                       /* time bomb FSM */


/*--------------------------------------------------------------------------*/
                                        /* the initial value of the timeout */
#define INIT_TIMEOUT   10

/*..........................................................................*/
static void Bomb4_ctor(Bomb4 *me, RAW_U8 defuse) {

	FSM_CONSTRUCTOR(&me->a1.super, (stm_state_handler)&Bomb4_initial);/* superclass ctor */
    me->defuse = defuse;    /* the defuse code is assigned at instantiation */
}
/*..........................................................................*/
static RAW_U16 Bomb4_initial(Bomb4 *me, STATE_EVENT  *e) {
    (void)e;
    me->timeout = INIT_TIMEOUT;
    return STM_TRAN(&Bomb4_setting);
}




/*..........................................................................*/
static RAW_U16 Bomb4_setting(Bomb4 *me, STATE_EVENT  *e) {
    switch (e->sig) {

		case STM_ENTRY_SIG: {
		
            me->code = 0;                          /* clear the defuse code */
            return STM_RET_HANDLED;
        }
		
        case UP_SIG: {
            
            ++me->timeout;
		
            printf("me->timeout is %d\n", me->timeout);
			       
            return STM_RET_HANDLED;
        }
        case DOWN_SIG: {
            if (me->timeout > 1) {
                --me->timeout;
				printf("me->timeout is %d\n", me->timeout);
            }
            return STM_RET_HANDLED;
        }
        case ARM_SIG: {
            return STM_TRAN(&Bomb4_timing);         /* transition to "timing" */
        }

		case STM_TIMEOUT_SIG:
		
			return STM_RET_HANDLED;
			 

			
		case STM_EXIT_SIG:
			printf("setting state exit\n");
			return STM_RET_HANDLED;
			
    }
    return STM_RET_IGNORED;
}





/*..........................................................................*/
static RAW_U16 Bomb4_timing(Bomb4 *me, STATE_EVENT *e) {
    switch (e->sig) {
        case STM_ENTRY_SIG: {
			
			idle_tick_arm(&l_bomb22.a1, 30);
			printf("timing state enter\n");
            me->code = 0;                          /* clear the defuse code */
            return STM_RET_HANDLED;
        }

		case STM_EXIT_SIG: {
			printf("timing state exit\n");
			return STM_RET_HANDLED;
		}
			
        case UP_SIG: {
            me->code <<= 1;
            me->code |= 1;
            return STM_RET_HANDLED;
        }
        case DOWN_SIG: {
            me->code <<= 1;
            return STM_RET_HANDLED;
        }
        case ARM_SIG: {
            if (me->code == me->defuse) {
                return STM_TRAN(&Bomb4_setting);
            }
            return STM_RET_HANDLED;
        }
        case STM_TIMEOUT_SIG: {

			idle_tick_arm(&l_bomb22.a1, 30);
			
            --me->timeout;
			
           printf("me->timeout is %d\n", me->timeout);
		   
            if (me->timeout == 0) {
							
				printf("boom aaaaaa^^^^^^%%%%%$$$$$$\n");
				RAW_ASSERT(0);
            }
           
           return STM_RET_HANDLED;
        }
		
    }
    return STM_RET_IGNORED;
}


static IDLE_QUEUE_MSG queue_bomb[3];

ACTIVE_EVENT_STRUCT_CB active_idle_task[] = {
	{ &l_bomb22.a1, queue_bomb, ARRAY_SIZE(queue_bomb)},
	
   
};



void bomb_test()
{
	
	RAW_ASSERT((ARRAY_SIZE(active_idle_task)) == MAX_IDLE_EVENT_TASK);
	
	idle_event_init();

	Bomb4_ctor(&l_bomb22, 0xd);       /* the secret defuse code, 1101 binary */

	fsm_init(&l_bomb22.a1.super, 0); 

	printf("Time Bomb (raw os fsm case)\n"
	   "Press 'u'   for UP   event\n"
	   "Press 'd'   for DOWN event\n"
	   "Press 'a'   for ARM  event\n");

}

void idle_event_user()
{
	__wfi();
 
}



